package com.mianyang.zhangsan.exception;

import com.mianyang.zhangsan.common.base.BaseController;
import com.mianyang.zhangsan.common.base.R;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author jiangjr
 * @date 2022-10-23
 */
@Slf4j
@RestControllerAdvice(basePackages = "com.mianyang.zhangsan.controller")
public class GlobalExceptionHandle extends BaseController {

    /**
     * token过期异常
     */
    @ExceptionHandler(ExpiredJwtException.class)
    public R expiredJwtExceptionHandle(ExpiredJwtException e, HttpServletRequest request) {
        log.error("请求地址，'{}',登录过期，请重新登录。", request.getRequestURI());
        return fail("登录过期，请重新登录。");
    }

    /**
     * 参数校验失败异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R methodArgumentNotValidExceptionHandle(MethodArgumentNotValidException e, HttpServletRequest request) {
        log.error("请求地址 '{}', 数据校验异常", request.getRequestURI());
        BindingResult bindingResult = e.getBindingResult();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        List<String> errors = fieldErrors.stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.toList());
        return fail(errors.toString());
    }
    /**
     * 业务异常
     */
    @ExceptionHandler(SecServiceException.class)
    public R secServiceExceptionHandle(SecServiceException e, HttpServletRequest request) {
        log.error("请求地址 '{}',业务异常 ----- {}", request.getRequestURI(), e.getMessage());
        return fail("业务异常，请联系管理员");
    }

    /**
     * 参数缺少异常
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public R missingServletRequestParameterExceptionHandle(MissingServletRequestParameterException e,
                                                           HttpServletRequest request) {
        log.error("请求地址 '{}', 参数缺少异常", request.getRequestURI());
        return fail("参数缺少" + e.getParameterName());
    }

    /**
     * 数据绑定异常
     */
    @ExceptionHandler(BindException.class)
    public R bindExceptionHandle(BindException e, HttpServletRequest request)
    {
        log.error("请求地址'{}', 发生数据绑定异常---'{}'",request.getRequestURI(), e.getMessage());
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return fail(message);
    }

    /**
     * 非法参数异常
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public R illegalArgumentExceptionHandle(IllegalArgumentException e, HttpServletRequest request) {
        log.error("请求地址'{}', 发生非法参数异常---'{}'",request.getRequestURI(), e.getMessage());
        return fail(e.getMessage());
    }

    /**
     * 未知运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public R runTimeExceptionHandle(RuntimeException e, HttpServletRequest request){
        log.error("请求地址'{}', 发生运行时异常---'{}'",request.getRequestURI(), e.getMessage());
        return fail(e.getMessage());
    }


    /**
     * 其他异常处理
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public R othersExceptionHandle(Exception e, HttpServletRequest request){
        log.error("请求地址'{}', 发生未知异常---'{}'",request.getRequestURI(), e.getMessage());
        return fail(e.getMessage());
    }
}
